home *** CD-ROM | disk | FTP | other *** search
- #include "VecLocal.h"
- #pragma hdrstop
-
- // copyright (c) 1992, 1993 by Paul Wheaton
-
- //.parse
-
- BitVector BitVector::operator|(const BitVector& BV) const
- {
- BitVector V=*this;
- V|=BV;
- return V;
- }
-
- //.parse
-
- void BitVector::operator|=(const BitVector& BV)
- {
- if (BV.Len>Alloc) ReAlloc((BV.Len+Extra)*8);
- long MinBytes=Min(BV.Len,Len);
- long I;
- For(I,MinBytes)
- {
- Byte huge* B=PtrInc(P,I);
- int X=(*B);
- X|=int(*PtrInc(BV.P,I));
- *B=Byte(X);
- }
- if (BV.Len>Len)
- {
- Len=BV.Len;
- for(I=MinBytes;I<Len;I++) (*PtrInc(P,I))=*PtrInc(BV.P,I);
- }
- BitLen=Max(BitLen,BV.BitLen);
- }
-
- //.parse
-
- Bool BitSetRef::operator=(Bool b)
- {
- #ifdef BorlandFixedByteMath
- if (b) *P |= M;
- else *P &= ~M;
- return b;
- #else
- int I=*P;
- if (b) I |= int(M);
- else I &= (255-int(M));
- *P=Byte(I);
- return b;
- #endif
- }
-
- //.parse
-
- Bool BitRef::operator=(Bool b)
- {
- #ifdef BorlandFixedByteMath
- if (b) *P |= M;
- else *P &= ~M;
- return b;
- #else
- int I=*P;
- if (b) I |= int(M);
- else I &= (255-int(M));
- *P=Byte(I);
- return b;
- #endif
- }
-
- //.parse
-
- void QSB(Byte* P, int Index, Bool b)
- {
- P+=size_t(Index/8);
- Byte M=Byte(1<<int(Index%8));
- #ifdef BorlandFixedByteMath
- if (b) *P |= M;
- else *P &= ~M;
- #else
- int I=*P;
- if (b) I |= int(M);
- else I &= (255-int(M));
- *P=Byte(I);
- #endif
- }
-
- //.parse
-
- BitRef::BitRef(Byte huge* BP, long BitOffset)
- {
- P=PtrInc(BP,BitOffset/8);
- M=Byte(1<<int(BitOffset%8));
- }
-
- //.parse
-
- void SetBitRange(void* BitPointer, long Index1,long Index2,Bool X)
- {
- Byte* P=(Byte*)BitPointer;
- if (Index1>Index2) return;
- long ByteIndex1=Index1/8;
- long ByteIndex2=Index2/8;
- Byte XByte=0;
- if (X)
- {
- X=1;
- XByte=255;
- }
- if (ByteIndex2>ByteIndex1+1)
- {
- long I;
- for(I=ByteIndex1+1;I<ByteIndex2;I++) *PtrInc(P,I)=XByte;
- }
- if (ByteIndex1==ByteIndex2)
- {
- Byte B1=Byte(Index1%8);
- Byte B2=Byte(Index2%8);
- Byte I;
- Byte huge* B=PtrInc(P,ByteIndex1);
- Byte Z=0;
- for(I=B1;I<=B2;I++) Z|=(1<<I);
- if (X) *B|=Z;
- else *B&=~Z;
- }
- else
- {
- Byte B=Byte(Index1%8); // the first bit num to set
- if (B==0) *PtrInc(P,ByteIndex1)=XByte; // set all the bits of this byte
- else
- {
- B=Byte(1<<B); // now B is a mask for the bit
- B--; // now B is a mask for all the previous bits
- Byte huge* BP=PtrInc(P,ByteIndex1);
- if (X) (*BP)|=~B;
- else (*BP)&=B; // all of the unmasked bits are cleared
- }
- B=Byte(Index2%8); // the last bit num to clear
- if (B==7) *PtrInc(P,ByteIndex2)=XByte; // set all the bits of this byte
- else
- {
- B=Byte(1<<(B+1)); // now B is a mask for the next bit
- B--; // now B is a mask for all the bits we want to clear
- Byte huge* BP=PtrInc(P,ByteIndex2);
- if (X) (*BP)|=B;
- else (*BP)&=~B; // all of the masked bits are cleared
- }
- }
- }
-
- //.parse
-
- BitVector::BitVector():ByteVector()
- {
- BitLen=0;
- Word I;
- For(I,Alloc) P[I]=0;
- }
-
- //.parse
-
- BitVector::BitVector(long I0,long I1):ByteVector()
- {
- long W[2];
- W[0]=I0;
- W[1]=I1;
- CtorsHelper(W,2);
- }
-
- //.parse
-
- BitVector::BitVector(long I0,long I1,long I2):ByteVector()
- {
- long W[3];
- W[0]=I0;
- W[1]=I1;
- W[2]=I2;
- CtorsHelper(W,3);
- }
-
-
- //.parse
-
- BitVector::BitVector(long I0,long I1,long I2,long I3):ByteVector()
- {
- long W[4];
- W[0]=I0;
- W[1]=I1;
- W[2]=I2;
- W[3]=I3;
- CtorsHelper(W,4);
- }
-
- //.parse
-
- BitVector::BitVector(long I0,long I1,long I2,long I3,long I4):ByteVector()
- {
- long W[5];
- W[0]=I0;
- W[1]=I1;
- W[2]=I2;
- W[3]=I3;
- W[4]=I4;
- CtorsHelper(W,5);
- }
-
- //.parse
-
- BitVector::BitVector(long I0,long I1,long I2,long I3,long I4,long I5):
- ByteVector()
- {
- long W[6];
- W[0]=I0;
- W[1]=I1;
- W[2]=I2;
- W[3]=I3;
- W[4]=I4;
- W[5]=I5;
- CtorsHelper(W,6);
- }
-
- //.parse
-
- BitVector::BitVector(long I0,long I1,long I2,long I3,long I4,long I5,long I6):
- ByteVector()
- {
- long W[7];
- W[0]=I0;
- W[1]=I1;
- W[2]=I2;
- W[3]=I3;
- W[4]=I4;
- W[5]=I5;
- W[6]=I6;
- CtorsHelper(W,7);
- }
-
- //.parse
-
- BitVector::BitVector(long I0,long I1,long I2,long I3,long I4,long I5,long I6,long I7):
- ByteVector()
- {
- long W[8];
- W[0]=I0;
- W[1]=I1;
- W[2]=I2;
- W[3]=I3;
- W[4]=I4;
- W[5]=I5;
- W[6]=I6;
- W[7]=I7;
- CtorsHelper(W,8);
- }
-
- //.parse
-
- BitVector::BitVector(long I0,long I1,long I2,long I3,long I4,long I5,long I6,long I7,long I8):
- ByteVector()
- {
- long W[9];
- W[0]=I0;
- W[1]=I1;
- W[2]=I2;
- W[3]=I3;
- W[4]=I4;
- W[5]=I5;
- W[6]=I6;
- W[7]=I7;
- W[8]=I8;
- CtorsHelper(W,9);
- }
-
- //.parse
-
- BitVector::BitVector(long I0):ByteVector()
- {
- long& W=long(I0);
- CtorsHelper(&W,1);
- }
-
- //.parse
-
- BitVector::BitVector(const BitVector& BV):ByteVector(BV)
- {
- BitLen=BV.BitLen;
- long I;
- for(I=Len;I<Alloc;I++) *PtrInc(P,I)=0;
- }
-
- //.parse
-
- void BitVector::ReAlloc(long NewCapacity)
- {
- long BN=BytesNeeded(NewCapacity);
- ByteVector::ReAlloc(BN);
- long I;
- for(I=Len;I<Alloc;I++) *PtrInc(P,I)=0;
- }
-
- //.parse
-
- static long* LongPtrInc(const long* P, long I)
- {
- return (long*)PtrInc((Byte*)P,I*4L);
- }
-
- void BitVector::CtorsHelper(const long* LP, long Length)
- {
- BitLen=0;
- long I;
- For(I,Length) BitLen=Max(*LongPtrInc(LP,I),BitLen);
- BitLen++;
- Len=BytesNeeded(BitLen);
- if (Len>Alloc) ReAlloc(BitLen+Extra);
- Clear();
- For(I,Length) Ref(*LongPtrInc(LP,I))=On;
- }
-
- //.parse
-
- void ClearBitRange(void* P, long Index1,long Index2)
- {
- SetBitRange(P,Index1,Index2,0);
- }
-
- //.parse
-
- void BitVector::ClearRange(long Index1,long Index2)
- {
- SetRange(Index1,Index2,0);
- }
-
- //.parse
-
- void BitVector::SetRange(long Index1,long Index2,Bool X)
- {
- if (Index1>Index2) return;
- if (Index2>=BitLen) Ref(Index2);
- SetBitRange(P,Index1,Index2,X);
- }
-
- //.parse
-
- void BitVector::operator=(const BitVector& BV)
- {
- Assign(BV);
- BitLen=BV.BitLen;
- long I;
- for(I=Len;I<Alloc;I++) *PtrInc(P,I)=0;
- }
-
- //.parse
-
- void BitVector::operator&=(const BitVector& BV)
- {
- long MinBytes=Min(BV.Len,Len);
- long I;
- For(I,MinBytes) (*PtrInc(P,I))&=*PtrInc(BV.P,I);
- if (BV.BitLen<BitLen)
- {
- for (I=BV.Len;I<Len;I++) *PtrInc(P,I)=0;
- Len=BV.Len;
- BitLen=BV.BitLen;
- if (Len>0)
- {
- Byte BitsToKill=Byte(7-int(BitLen%8));
- Byte huge* B=PtrInc(P,Len-1);
- *B<<=BitsToKill;
- *B>>=BitsToKill;
- }
- }
- }
-
- //.parse
-
- BitVector::operator String() const
- {
- Word Stop=Word(Min(long(BitLen),long(65500L))); // the max for a malloc
- String S('0',Stop);
- Word I;
- For(I,Stop)
- if (At(I)) S[I]='1';
- return S;
- }
-
- //.parse
-
- #define BitVecRefGuts \
- long BN=BytesNeeded(Index+1); \
- if (BN>Alloc) ReAlloc(Index+DefaultVectorExtra); \
- if (Index>=BitLen) \
- { \
- BitLen=Index+1; \
- Len=BN; \
- } \
- return BitRef(P,Index);
-
- BitRef BitVector::Ref(long Index)
- {
- BitVecRefGuts
- }
-
- BitRef BitVector::operator[](long Index)
- {
- BitVecRefGuts
- }
-
- //.parse
-
- Bool BitVector::At(long Index) const
- {
- if (Index>BitLen) return False;
- else return (( (*PtrInc(P,Index/8)) & (1<<(Index%8)) )!=0);
- }
-
- //.parse
-
- BitVector BitVector::At(long Index,long Length) const
- {
- BitVector BV;
- BV.ReAlloc(Length);
- long I;
- For(I,Length)
- if ((*this)(Index+I)) BV[I]=1;
- return BV;
- }
-
- //.parse
-
- BitVector BitVector::From(long Index) const
- {
- long Length=(Index>BitLen)?0:BitLen-Index;
- return At(Index,Length);
- }
-
- //.parse
-
- BitVector BitVector::After(long Index) const
- {
- long Length=(Index>=BitLen)?0:BitLen-Index-1;
- return At(Index+1,Length);
- }
-